home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Demo / www / gopher.py < prev    next >
Text File  |  1996-03-12  |  6KB  |  265 lines

  1. #! /usr/local/bin/python
  2.  
  3. # A *very* simple interactive gopher client
  4. #
  5. # Usage: gopher [ [selector] host [port] ]
  6.  
  7. import string
  8. import sys
  9. import os
  10. import socket
  11. from gopherlib import *
  12.  
  13. # Browser main command, has default arguments
  14. def browser(*args):
  15.     selector = DEF_SELECTOR
  16.     host = DEF_HOST
  17.     port = DEF_PORT
  18.     n = len(args)
  19.     if n > 0 and args[0]:
  20.         selector = args[0]
  21.     if n > 1 and args[1]:
  22.         host = args[1]
  23.     if n > 2 and args[2]:
  24.         port = args[2]
  25.     if n > 3:
  26.         raise RuntimeError, 'too many args'
  27.     try:
  28.         browse_directory('*** TOPLEVEL ***', selector, host, port)
  29.     except socket.error, msg:
  30.         print 'Socket error:', msg
  31.         sys.exit(1)
  32.     except KeyboardInterrupt:
  33.         print '\n[Goodbye]'
  34.  
  35. # Browse a directory
  36. def browse_directory(description, selector, host, port):
  37.     list = get_directory(send_selector(selector, host, port))
  38.     while 1:
  39.         print '----- MENU:', description, '-----'
  40.         print 'Selector:', `selector`
  41.         print 'Host:', host, ' Port:', port
  42.         print
  43.         for i in range(len(list)):
  44.             item = list[i]
  45.             gtype, descr = item[0], item[1]
  46.             print string.rjust(`i+1`, 3) + ':', descr, \
  47.                 '<' + type_to_name(gtype) + '>'
  48.         print
  49.         while 1:
  50.             try:
  51.                 str = raw_input('Choice [CR == up a level]: ')
  52.             except EOFError:
  53.                 print
  54.                 return
  55.             if not str:
  56.                 return
  57.             try:
  58.                 choice = string.atoi(str)
  59.             except string.atoi_error:
  60.                 print 'Choice must be a number; try again:'
  61.                 continue
  62.             if not 0 < choice <= len(list):
  63.                 print 'Choice out of range; try again:'
  64.                 continue
  65.             break
  66.         item = list[choice-1]
  67.         [gtype, i_descr, i_sel, i_host, i_port] = item[:5]
  68.         if typebrowser.has_key(gtype):
  69.             browserfunc = typebrowser[gtype]
  70.         else:
  71.             print 'Unsupported file type', `gtype`, '--> binary'
  72.             browserfunc = browse_binary
  73.         try:
  74.             browserfunc(i_descr, i_sel, i_host, i_port)
  75.         except (IOError, socket.error):
  76.             print '***', sys.exc_type, ':', sys.exc_value
  77.  
  78. # Browse a text file
  79. def browse_textfile(description, selector, host, port):
  80.     print '----- TEXTFILE:', description, '-----'
  81.     print 'Selector:', `selector`
  82.     print 'Host:', host, ' Port:', port
  83.     print
  84.     cf = send_selector(selector, host, port)
  85.     x = None
  86.     try:
  87.         p = os.popen('${PAGER-more}', 'w')
  88.         x = SaveLines(p)
  89.         get_alt_textfile(cf, x.writeln)
  90.     except IOError, msg:
  91.         print 'IOError:', msg
  92.     if x:
  93.         x.close()
  94.     f = open_savefile()
  95.     if not f:
  96.         return
  97.     cf = send_selector(selector, host, port)
  98.     x = SaveLines(f)
  99.     try:
  100.         get_alt_textfile(cf, x.writeln)
  101.         print 'Done.'
  102.     except IOError, msg:
  103.         print 'IOError:', msg
  104.     x.close()
  105.  
  106. # Browse a search index
  107. def browse_index(description, selector, host, port):
  108.     while 1:
  109.         print '----- SEARCH:', description, '-----'
  110.         print 'Selector:', `selector`
  111.         print 'Host:', host, ' Port:', port
  112.         print
  113.         try:
  114.             query = raw_input('Query [CR == up a level]: ')
  115.         except EOFError:
  116.             print
  117.             break
  118.         query = string.strip(query)
  119.         if not query:
  120.             break
  121.         if '\t' in query:
  122.             print 'Sorry, queries cannot contain tabs'
  123.             continue
  124.         browse_directory('Search outcome', \
  125.             selector + TAB + query, host, port)
  126.  
  127. # "Browse" telnet-based information, i.e. open a telnet session
  128. def browse_telnet(description, selector, host, port):
  129.     cmd = 'telnet'
  130.     if selector:
  131.         cmd = cmd + ' -l ' + selector
  132.     cmd = cmd + ' ' + host
  133.     if port:
  134.         cmd = cmd + ' ' + port
  135.     print '----- EXEC:', cmd, '-----'
  136.     sts = os.system(cmd)
  137.     if sts:
  138.         print 'Exit status:', sts
  139.  
  140. # "Browse" a binary file, i.e. save it to a file
  141. def browse_binary(description, selector, host, port):
  142.     print '----- BINARY:', description, '-----'
  143.     print 'Selector:', `selector`
  144.     print 'Host:', host, ' Port:', port
  145.     print
  146.     f = open_savefile()
  147.     if not f:
  148.         return
  149.     cf = send_selector(selector, host, port)
  150.     x = SaveWithProgress(f)
  151.     get_alt_binary(cf, x.write, 8*1024)
  152.     x.close()
  153.  
  154. # "Browse" a sound file, i.e. play it or save it
  155. def browse_sound(description, selector, host, port):
  156.     print '----- SOUND:', description, '-----'
  157.     print 'Selector:', `selector`
  158.     print 'Host:', host, ' Port:', port
  159.     print
  160.     f = open_savefile() # Use |playulaw, for instance
  161.     if not f:
  162.         return
  163.     cf = send_selector(selector, host, port)
  164.     x = SaveWithProgress(f)
  165.     get_alt_binary(cf, x.write, 8000) # Exactly 8000 bytes/sec!
  166.     x.close()
  167.  
  168. # Deny browsing an entry
  169. def browse_not(description, selector, host, port):
  170.     print '----- DENIED:', description, '-----'
  171.     print 'It would be unwise to connect to host', host, 'and port', port
  172.     print 'since the type of connection does not yield a file.'
  173.  
  174. # Dictionary mapping types to browser functions
  175. typebrowser = { \
  176.     A_FILE: browse_textfile, \
  177.     A_DIRECTORY: browse_directory, \
  178.     A_INDEX: browse_index, \
  179.     A_TELNET: browse_telnet, \
  180.     A_UNIXBIN: browse_binary, \
  181.     A_SOUND: browse_sound, \
  182.     A_TN3270: browse_not, \
  183.     'Z': browse_directory, \
  184.     }
  185.  
  186. # Class used to save lines, appending a newline to each line
  187. class SaveLines:
  188.     def __init__(self, f):
  189.         self.f = f
  190.     def writeln(self, line):
  191.         self.f.write(line + '\n')
  192.     def close(self):
  193.         sts = self.f.close()
  194.         if sts:
  195.             print 'Exit status:', sts
  196.  
  197. # Class used to save data while showing progress
  198. class SaveWithProgress:
  199.     def __init__(self, f):
  200.         self.f = f
  201.     def write(self, data):
  202.         sys.stdout.write('#')
  203.         sys.stdout.flush()
  204.         self.f.write(data)
  205.     def close(self):
  206.         print
  207.         sts = self.f.close()
  208.         if sts:
  209.             print 'Exit status:', sts
  210.  
  211. # Ask for and open a save file, or return None if not to save
  212. def open_savefile():
  213.     try:
  214.         savefile = raw_input( \
  215.         'Save as file [CR == don\'t save; |pipeline or ~user/... OK]: ')
  216.     except EOFError:
  217.         print
  218.         return None
  219.     savefile = string.strip(savefile)
  220.     if not savefile:
  221.         return None
  222.     if savefile[0] == '|':
  223.         cmd = string.strip(savefile[1:])
  224.         try:
  225.             p = os.popen(cmd, 'w')
  226.         except IOError, msg:
  227.             print `cmd`, ':', msg
  228.             return None
  229.         print 'Piping through', `cmd`, '...'
  230.         return p
  231.     if savefile[0] == '~':
  232.         savefile = os.path.expanduser(savefile)
  233.     try:
  234.         f = open(savefile, 'w')
  235.     except IOError, msg:
  236.         print `savefile`, ':', msg
  237.         return None
  238.     print 'Saving to', `savefile`, '...'
  239.     return f
  240.  
  241. # Main program
  242. def main():
  243.     if sys.argv[4:]:
  244.         print 'usage: gopher [ [selector] host [port] ]'
  245.         sys.exit(2)
  246.     elif sys.argv[3:]:
  247.         browser(sys.argv[1], sys.argv[2], sys.argv[3])
  248.     elif sys.argv[2:]:
  249.         try:
  250.             port = string.atoi(sys.argv[2])
  251.             selector = ''
  252.             host = sys.argv[1]
  253.         except string.atoi_error:
  254.             selector = sys.argv[1]
  255.             host = sys.argv[2]
  256.             port = ''
  257.         browser(selector, host, port)
  258.     elif sys.argv[1:]:
  259.         browser('', sys.argv[1])
  260.     else:
  261.         browser()
  262.  
  263. # Call the test program as a main program
  264. main()
  265.